package com.xlh.util;

import com.alibaba.fastjson.JSON;
import com.xlh.constant.UserConstant;
import com.xlh.enums.SmsEnum;
import com.xlh.exception.common.GlobalException;
import com.xlh.properties.SmsProperties;
import lombok.Data;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

/**
 * 短信发送
 * <p>
 * Created by lx on 2020/3/11.
 */
public class SmsUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(SmsUtil.class);

    private static SmsProperties smsProperties = SpringContextUtil.getBean(SmsProperties.class);

    private static String sid = "6f53264d05bc43bcafc1a47b30fdd296";

    private static String token = "2a9afc0b29e842339172790584e6e40d";

    private static String name = "【华育兴业】";

    public static void send(String telephone, String code) {

        long timestamp = System.currentTimeMillis();
        String sig = DigestUtils.md5Hex(SmsUtil.getSid() + SmsUtil.getToken() + timestamp);

        String smsContent = String.format("%s您的验证码为%s，请于%s分钟内正确输入，如非本人操作，请忽略此短信。",
                SmsUtil.getName(), code, UserConstant.SMS_CODE_EXPIRED_TIME / 60);
        String body = String.format("accountSid=%s&to=%s&smsContent=%s&timestamp=%s&sig=%s",
                SmsUtil.getSid(), telephone, smsContent, timestamp, sig);

        String data = "";
        try {
            data = post("https://openapi.miaodiyun.com/distributor/sendSMS", body);
        } catch (Exception e) {
            throw new GlobalException("发送短信失败");
        }

        if (StringUtils.isBlank(data)) {
            throw new GlobalException("发送短信失败");
        }

        MessageDTO responseObj = JSON.parseObject(data, MessageDTO.class);
        SmsEnum smsEnum = SmsEnum.getByCode(responseObj.getRespCode());
        if (smsEnum == null) {
            throw new GlobalException("发送短信失败");
        }
        if (smsEnum != null && smsEnum == SmsEnum.SUCCESS
                && CollectionUtils.isEmpty(responseObj.getFailList())) {
            return;
        }
        smsEnum = SmsEnum.getByCode(responseObj.getFailList().get(0).getRespCode());
        LOGGER.error("send sms fail message: {}", data);

        throw new GlobalException(smsEnum == null ? "发送短信失败" : smsEnum.getMessage());


    }

    /**
     * post请求
     *
     * @param url
     * @param body
     * @return
     */
    public static String post(String url, String body) throws Exception {

        String result = "";

        OutputStreamWriter out = null;
        BufferedReader in = null;
        URL realUrl = new URL(url);
        URLConnection conn = realUrl.openConnection();

        // 设置连接参数
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setConnectTimeout(5000);
        conn.setReadTimeout(20000);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        // 提交数据
        out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
        out.write(body);
        out.flush();

        // 读取返回数据
        in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
        String line = "";
        boolean firstLine = true; // 读第一行不加换行符
        while ((line = in.readLine()) != null) {
            if (firstLine) {
                firstLine = false;
            } else {
                result += System.lineSeparator();
            }
            result += line;
        }


        return result;
    }

    public static String getSid() {
        if (StringUtils.isNotBlank(smsProperties.getSid())) {
            return smsProperties.getSid();
        }
        return sid;
    }

    public static String getToken() {
        if (StringUtils.isNotBlank(smsProperties.getToken())) {
            return smsProperties.getToken();
        }
        return token;
    }

    public static String getName() {
        if (StringUtils.isNotBlank(smsProperties.getName())) {
            return smsProperties.getName();
        }
        return name;
    }

}

@Data
class MessageDTO {

    private String respDesc;

    private String smsId;

    private List<FailMessageDTO> failList;

    private String respCode;

}

@Data
class FailMessageDTO {

    private String phone;

    private String respCode;

}

